package cpmake.addons.ivy;

import cpmake.DependencyCache;
import cpmake.rules.AbstractRule;
import cpmake.rules.Rule;
import cpmake.MakeAction;
import cpmake.CPMakeException;
import cpmake.addons.java.ClasspathProvider;
import cpmake.addons.java.Classpath;
import cpmake.CPMake;

import java.util.ArrayList;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.ivy.Ivy;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.util.DefaultMessageLogger;
import org.apache.ivy.util.Message;

public class ResolveRule extends AbstractRule<ResolveRule>
		implements MakeAction
	{
	private File m_ivyFile;
	private File m_settingsFile;
	private Set<String> m_configurations = new HashSet<String>();
	private ResolveReport m_report = null;
	private Ivy m_ivy;
	private DependencyCache m_cache = null;
	private boolean m_run = false;

		//---------------------------------------------------------------------------
	private class ResolveRuleClasspathProvider implements ClasspathProvider
		{
		private String m_configuration;
		
		public ResolveRuleClasspathProvider(String configuration)
			{
			m_configuration = configuration;
			}
			
		public Classpath getClasspath()
				throws CPMakeException
			{
			return (ResolveRule.this.getClasspath(m_configuration));
			}
		}
	
	//---------------------------------------------------------------------------
	/*package*/ ResolveRule(File ivyFile, File settingsFile, Set<String> configurations)
		{
		super();
		//setName("ivy-resolve");
		m_ivyFile = ivyFile;
		setMakeAction(this);
		m_ivy = Ivy.newInstance();
		m_settingsFile = settingsFile;
		m_configurations = configurations;
		}
		
	//---------------------------------------------------------------------------
	public Iterable<String> getTargets()
		{
		return (new ArrayList<String>());
		}
		
	//---------------------------------------------------------------------------
	public boolean needToRun() { return (m_run); }
	
	//---------------------------------------------------------------------------
	public void preBuild(DependencyCache cache)
		{
		m_cache = cache;

		m_run = true;
		}
		
	//---------------------------------------------------------------------------
	/**
	 This report is available after the rule has ran
	 @return
	 */
	public ResolveReport getReport() { return (m_report); }

	//---------------------------------------------------------------------------
	/**
	 Returns the ivy instance used for performing this resolve
	 @return
	 */
	public Ivy getIvyInstance() { return (m_ivy); }

	//---------------------------------------------------------------------------
	public ClasspathProvider getClasspathProvider(String configuration)
		{
		return (new ResolveRuleClasspathProvider(configuration));	
		}
		
	//---------------------------------------------------------------------------
	public Classpath getClasspath(String configuration)
			throws CPMakeException
		{
		if (m_report == null)
			throw new CPMakeException("You cannot call ResolveRule.getClasspath until after the rule as been ran", -1);
			
		Classpath cp = new Classpath();

		for (String s : m_report.getConfigurations())
			System.out.println(s);
		ArtifactDownloadReport[] deps = m_report.getConfigurationReport(configuration)
				.getAllArtifactsReports();
				
		for (ArtifactDownloadReport rep : deps)
			{
			if (rep.getType().equals("jar"))
				cp.addPath(rep.getLocalFile().getPath());
			}
		
		return (cp);
		}
	
	//---------------------------------------------------------------------------
	public void doMakeAction(Rule rule)
			throws CPMakeException
		{
		try
			{
			System.out.println("Ivy resolving dependencies.");

			if (!m_make.getProperty(CPMake.PROP_VERBOSE, "false").equals("true"))
				m_ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_WARN));
			
			if (m_settingsFile != null)
				m_ivy.configure(m_settingsFile);
			else
				m_ivy.configureDefault();
				
			ResolveOptions ro = new ResolveOptions();
			//ro.setValidate(false);
			//ro.setUseCacheOnly(false);
			//ro.setCheckIfChanged(false);

			if (m_configurations.size() != 0)
				ro.setConfs(m_configurations.toArray(new String[0]));

			//ro.setUseCacheOnly(false);
			//ro.setRefresh(true);
			
			m_report = m_ivy.resolve(m_ivyFile.toURI().toURL(), ro);
			
			if (m_report.hasError())
				throw new CPMakeException("Unable to resolve dependencies", -1);
			}
		catch (java.net.MalformedURLException e)
			{
			throw new CPMakeException(e);
			}
		catch (java.text.ParseException e)
			{
			throw new CPMakeException(e);
			}
		catch (java.io.IOException e)
			{
			throw new CPMakeException(e);
			}
		}
	}
